package cn.biplam.common.wrapper.sqlresult;

import java.io.Serializable;
import java.sql.ResultSetMetaData;

import cn.biplam.common.wrapper.KvMap;

/**
 * 用于获取SqlResultSet对象中列类型和属性信息
 * @author XiaoRuxing
 * @create 3:30:17 PM
 * @version 1.0
 */                                     
public class SqlResultMetaData implements Serializable{
	private static final long serialVersionUID = -6936099369891340284L;//类编号
	private  int  	  icolumnCount;			//字段数量
	private  String  sDbType; 				//数据库类型
	private  String  sDbVersion;			//数据库版本
	private  KvMap<String,Integer>  kvmColumnMap;  //存储列名和列编号映射关系
	private  String[] hmColumnTypeMap;     //存储列的数据类型
	private  int[] hmColumnLength ;   //存储每列字段长度

	/**
	 * 数据集对象行操作标志
	 */
	public enum Sql_Result_Row_Opt_Flag{
		/** 不操作 */
		NOTHING("0"),
		/** 更新操作 */
		UPDATE("1"),
		/** 添加操作 */
		INSERT("2"),
		/** 删除操作 */
		DELETE("3");
		private String value;
		private Sql_Result_Row_Opt_Flag(String value){this.value=value;}
		public String toString() {return value;}
	}

	/**
	 * 数据集对象字段操作标志
	 */
	public enum Sql_Result_Column_Opt_Flag{
		/** 不操作 */
		NOTHING("0"),
		/** 更新操作 */
		UPDATE("1");
		private String value;
		private Sql_Result_Column_Opt_Flag(String value){this.value=value;}
		public String toString() {return value;}
	}

	/**
	 * 构造函数
	 * @param rsMetaData 数据集元数据对象
	 * @throws Exception 当数据链接发生异常时，抛出SQL异常
	 */
	public SqlResultMetaData(ResultSetMetaData rsMetaData) throws Exception{
		this.icolumnCount=rsMetaData.getColumnCount();
		init(rsMetaData);
	}

	/**
	 * 	初始化成员变量,保存每列数据类型和排序方式，存储列名和列编号映射关系
	 * @param rsMetaData  数据集元数据对象
	 * @throws Exception 当数据链接发生异常时，抛出SQL异常
	 */
	private  void init(ResultSetMetaData rsMetaData) throws Exception{
		kvmColumnMap=new KvMap<String,Integer>();
		hmColumnTypeMap=new String [icolumnCount];
		hmColumnLength=new int[icolumnCount];
		setColumnMap(rsMetaData);
		setColumnTypeMap(rsMetaData);
		setColumnLength(rsMetaData);
	}

	/**
	 * 	保存每列数据类型到对象
	 * @param rsMetaData 数据集元数据对象
	 * @throws Exception 当数据链接发生异常时，抛出SQL异常
	 */
	private void setColumnTypeMap(ResultSetMetaData rsMetaData) throws Exception{
		for(int i=0;i<icolumnCount;i++){
			hmColumnTypeMap[i]=rsMetaData.getColumnTypeName(i+1);
		}
	}

	/**
	 * 	保存列序号和列名映射关系
	 * @param rsMetaData 数据集元数据对象
	 * @throws Exception 当数据链接发生异常时，抛出SQL异常
	 */
	private void setColumnMap(ResultSetMetaData rsMetaData) throws Exception{
		for(int i=0;i<icolumnCount;i++){
			kvmColumnMap.put(rsMetaData.getColumnName(i+1).toUpperCase(),i);
		}
	}

	/**
	 * 	保存每列列宽
	 * @param rsMetaData 数据集元数据对象
	 * @throws Exception 当数据链接发生异常时，抛出SQL异常
	 */
	private void setColumnLength(ResultSetMetaData rsMetaData) throws Exception{
		for(int i=0;i<icolumnCount;i++){
			hmColumnLength[i]=rsMetaData.getPrecision(i+1);
		}
	}

	/**
	 * 	返回数据集对象列数
	 * @return	数据集对象列数
	 */
	public int getColumnCount(){
		return icolumnCount;
	}

	/**
	 * 	获取指定列名称，第一列0，第二列1
	 * @param iColumn 列序号
	 * @return 列名称
	 */
	public String getColumnNameByIndex(int iColumnIndex){
		return kvmColumnMap.getByValue(iColumnIndex);
	}

	/**
	 * 	获取指定列名序号，第一列0，第二列1
	 * @param sColumnName 列名
	 * @return 列序号
	 */
	public int getColumnIndexByName(String  sColumnName){
		if(sColumnName!=null){
			sColumnName = sColumnName.toUpperCase();
			sColumnName = sColumnName.trim();
		}
		if(kvmColumnMap.getByKey(sColumnName)!=null){
			return kvmColumnMap.getByKey(sColumnName);			
		}else{
			return -1;
		}
	}

	/**
	 * 	获取指定列数据类型
	 * @param sColumnName 列名
	 * @return 列数据类型
	 */
	public String getColumnTypeByName(String sColumnName){
		int iColumnIndex=getColumnIndexByName(sColumnName);
		if(iColumnIndex!=-1&&iColumnIndex<icolumnCount){
			return hmColumnTypeMap[iColumnIndex];
		}
		return null;
	}

	/**
	 * 	获取指定列数据类型，第一列1，第二列2
	 * @param iColumnIndex 列序号
	 * @return 列数据类型
	 */
	public String getColumnTypeByIndex(int iColumnIndex){
		if(iColumnIndex!=-1&&iColumnIndex<icolumnCount){
			return hmColumnTypeMap[iColumnIndex];
		}
		return null;
	}

	/**
	 * 	获取指定列数据长度
	 * @param sColumnName 列名
	 * @return	列数据长度
	 */
	public int getColumnLengthByName(String sColumnName){
		int iColumnIndex=getColumnIndexByName(sColumnName);
		if(iColumnIndex!=-1&&iColumnIndex<icolumnCount){
			return hmColumnLength[iColumnIndex];
		}
		return 0;
	}

	/**
	 * 	获取指定列数据长度，第一列1，第二列2
	 * @param iColumnIndex 列序号
	 * @return	列数据长度
	 */
	public int getColumnLengthByIndex(int iColumnIndex){
		if(iColumnIndex!=-1&&iColumnIndex<icolumnCount){
			return hmColumnLength[iColumnIndex];
		}
		return 0;
	}

	/**
	 * 	返回记录集数据库类型
	 * @return 数据库类型
	 */
	public String getDatabaseType (){
		return sDbType;
	}

	/**
	 * 	返回记录集数据库版本
	 * @return 数据库版本
	 */
	public String getDatabaseVersion(){
		return sDbVersion;
	}

	/**
	 * 返回Metadata的文本说明
	 * @return	String
	 */
	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<this.icolumnCount;i++){
			sb.append(this.kvmColumnMap.getByValue(i));
			sb.append("[");
			sb.append(hmColumnTypeMap[i]);
			sb.append(",");
			sb.append(this.hmColumnLength[i]);
			sb.append("]\n");
		}
		return sb.toString();
	}

}
